#define xuser mixc::powerful_cat
#include"algo/hash.hpp"
#include"lang/cxx.hpp"
#include"math/random.hpp"
#include"mixc.hpp"
#include"utils/counter.hpp"

xinit(xuser::the_main){
    using namespace xuser;
    counter demo = 0;

    // 演示：hash 普通数值类型
    {
        xhint(demo);
        xhint(hash(1024));
        xhint(hash('a'));

        // 浮点也可以进行 hash，但需要使用者保证不存在精度问题
        xhint(hash(3.1415926));
    }

    // 演示：hash 原始字符串类型
    {
        xhint(demo);

        xhint(hash("hello world"));         // 实际上 s 和 a 这两个传入的参数类型是不一样的
        xhint(hash(asciis("hello world"))); // 前者是字符数组，后者是字符指针，但我们保证了一致性
    }

    // 演示：hash cxx
    {
        xhint(demo);

        xhint(hash(c08("hello world")));    // 对于 ascii 字符串，c08 和 c16 hash 的结果是一样的
        xhint(hash(c16(u"hello world")));   

        xhint(hash(c08("hello!小猫爱编程")));    // 对于包含了非 ascii 字符串，c08 和 c16 hash 结果是不一样的
        xhint(hash(c16(u"hello!小猫爱编程")));
    }

    // 演示：hash 未知类型
    {
        xhint(demo);

        struct { u08 bytes[10]; }unknown;

        // 支持 hash 结构体、联合体、类
        xhint(hash(unknown));
    }

    // 演示：使用 hash 函数第二个参数避免 hash 攻击
    {
        xhint(demo);

        // 弱口令
        xhint(hash("123456"));

        // 带随机数的弱口令
        xhint(hash("123456", random<uxx>()));
    }

    // 演示：不同字节数的整数也会有相同的 hash 值
    {
        xhint(demo);

        xhint(hash(u08('a')));
        xhint(hash(u16('a')));
    }
};